import jsMd5 from 'js-md5'
import QRcode from 'qrcodejs2'
import JSEncrypt from 'jsencrypt'
import VConsole from "vconsole";
import Config from '@/api/config'
import { Dialog } from 'vant'


String.prototype.format = function () {
  var args = arguments
  return this.replace(/{(\d+)}/g, function (m, i) {
    return args[i] || ''
  })
}

String.prototype.toMoney = function () {
  let s = this.split('.')
  let s0 = s[0]
  let end = s0.length % 3
  let arr = []
  if (end != 0) {
    arr.push(s0.substring(0, end))
  }
  let count = Math.floor(s0.length / 3)
  if (count > 0) {
    s0 = s0.substring(end)
    do {
      arr.push(s0.substring(0, 3))
      s0 = s0.substring(3)
    } while (s0.length)
  }
  s[0] = arr.join(',')
  return s.join('.')
}

Date.prototype.format = function (format) {
  format = format || 'yyyy-MM-dd HH:mm:ss'
  let f = function (m) {
    return m < 10 ? `0${m}` : m
  }
  let str = format.replace('yyyy', this.getFullYear())
  str = str.replace('MM', f(this.getMonth() + 1))
  str = str.replace('dd', f(this.getDate()))
  str = str.replace('HH', f(this.getHours()))
  str = str.replace('mm', f(this.getMinutes()))
  str = str.replace('ss', f(this.getSeconds()))
  return str
}

const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent)

const md5 = function(val) {
  return jsMd5(val)
}

/**
 * 加密密码
 * @param {*} pwd 密码
 * @param {*} publickey 加密公钥
 */
const encryptPwd = function (publickey, pwd) {
  var encrypt = new JSEncrypt()
  encrypt.setPublicKey(publickey)
  pwd = encrypt.encrypt(pwd)
  return pwd
}

// 64 位随机字符串
const randomString = () => {
  const str = '!@#*&%())#'
  const date = new Date().getTime() + ''
  const _str = md5(str + date) + md5(date)
  return _str
}

// 保留小数位，非四舍五入
const toFixed = function(data, num){
  data = Number(data).toFixed(10)
  let _digit = (num?data.lastIndexOf(".") + num + 1:data.lastIndexOf("."))
  data = data.substring(0, _digit)
  return data
}

//部分密文显示
const ciphertext = function(value, start, end) {
  value = value + ''
  var _s = value.substring(0, start||3)
  var _e = value.substring(value.length - end||3, value.length)
  return `${_s}****${_e}`
}

//获取客户端类型
const getPhonePlatform = () => {
  let _platform = 'h5'
  let isAndroid = navigator.userAgent.indexOf('Android') > -1 || navigator.userAgent.indexOf('Linux') > -1
  if (isAndroid) {
      _platform = 'android'
  }
  let isiOS = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
  if (isiOS) {
      _platform = 'ios'
  }
  return _platform
}

// 移除结尾0
const removeEndZero = function (str) {
  // str = Number(str)
  str = str.toString().split('.')
  if (str[1]) {
    str[1] = str[1].replace(/[0]+$/, '')
  }
  return str[1] && str[1].length ? str.join('.') : str.join('')
}

// 如果是 '' 默认为 0.00 显示
const defaultZero = function (value) {
    return value === '' ? '0.00' : value
}
  
/*倒计时
t 倒计时长，单位秒
opt 参数
callback Function 带当前倒计时时间参数回调
format  String 倒计时模板
finished Function 倒计时完毕回调执行函数
 */
const countDown = function (t, opt) {
  const format = opt.format || 'dd HH:mm:ss'
  var f = function (m) {
    return m < 10 ? '0' + m : m
  }
  function a () {
    t = Math.max(t - 1, 0)
    if(t <= 0){
      clearInterval(interval)
      typeof opt.finished === 'function' && opt.finished()
    }
    let str = format
    str = str.replace('dd', f(Math.floor(t / (60*60*24))))
    str = str.replace('HH', f(Math.floor(t / (60*60))))
    str = str.replace('mm', f(Math.floor(t / 60)))
    str = str.replace('ss', f(Math.floor(t % 60)))
    if (typeof opt.callback === 'function') {
      opt.callback(str)
    }
  }
  a()
  let interval = setInterval(a, 1000)
  return interval
}

//固定显示长度不足补0
const fitLen = function (num, length) {
  num = '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + num
  return num.slice(num.length - length)
}

// 生成二维码并优化截图时二维码白屏问题
const qrcode = function (dom, text, opts) {
  typeof dom == 'string' && (dom = document.querySelector(dom))
  if (!dom) {
    console.error('QRcode: Need a element to append child')
    return
  }
  dom.innerHTML = ''
  opts = opts || {}
  opts.text = text
  opts.width = opts.width || 256
  opts.height = opts.height || 256
  opts.colorDark = opts.colorDark || "#000000"
  opts.colorLight = opts.colorLight || "#ffffff"
  const qrcode = new QRcode(dom, opts)
  setTimeout(()=>{
    let img = qrcode._oDrawing._elImage
    let canvas = qrcode._oDrawing._elCanvas
    img.src = canvas.toDataURL('image/png')
    img.removeAttribute('style')
    canvas.remove()
  },0)
  
  return qrcode
}

//顶象验证通用函数
let Captcha = null
const getCaptcha = function(){
  return new Promise((resolve, reject)=>{
    if(!Captcha){
      Captcha = _dx.Captcha(document.getElementById('captcha'), {
        appId: 'e8866e360479c39ce9f4a93d091667eb',
        style:'popup'
      })
    } else {
      Captcha.reload()
    }
    Captcha.on('verifySuccess', (token)=>{
      Captcha.hide()
      resolve(token)
    })
    Captcha.show()
  })
}

//检测颜色值是否为亮色
const isLightColor = function(hexString){
  let _r, _g, _b, _light
  if (hexString.charAt(0) !== "#") {
      hexString = "#" + hexString;
  }
  if (hexString.length === 4) {
      let split = hexString.split("");
      hexString = "#" + split[1] + split[1] + split[2] + split[2] + split[3] + split[3];
  }

  hexString = hexString.substring(hexString.length-6,hexString.length);
  _r = parseInt("0x" + hexString.slice(0, 2))
  _g = parseInt("0x" + hexString.slice(2, 4))
  _b = parseInt("0x" + hexString.slice(4, 6))
  _light = _r * 0.299 + _g * 0.587 + _b * 0.114
  return _light >= 192 ? true : false
}

// 获取光标位置
const getCursortPosition = function (dom) {
  var cursorPos = 0
  if (document.selection) {
    // IE Support
    dom.focus()
    var selectRange = document.selection.createRange()
    selectRange.moveStart ('character', -dom.value.length)
    cursorPos = selectRange.text.length;
  } else if (dom.selectionStart || dom.selectionStart == '0') {
    // Firefox support
    cursorPos = dom.selectionStart;
  }
  return cursorPos
}

// 设置光标位置
const setCursortPosition = function (dom, pos) {
  if (dom.setSelectionRange) {
    // IE Support
    dom.focus()
    dom.setSelectionRange(pos, pos)
  } else if (dom.createTextRange) {
    // Firefox support
    var range = dom.createTextRange()
    range.collapse(true)
    range.moveEnd('character', pos)
    range.moveStart('character', pos)
    range.select()
  }
}

// 数字人性化显示
const humanNum = function (number, digit=2) {
  try {
    let _n = parseFloat(number), rst, unit = '';
    if (_n / 100000000 > 1) {
      rst = _n / 100000000;
      unit = $i18n.t('亿');
    } else if (_n / 10000 > 1) {
      rst = _n / 10000;
      unit = $i18n.t('万');
    } else {
      rst = _n;
    }
    return toFixed(rst, digit) + unit;
  } catch (e) {
    return number;
  }
}

//时间格式人性化
const humanTime = function(msec) {
  var days = parseInt(msec / 1000 / 60 / 60 / 24, 10); //计算剩余的天数
  var hours = parseInt(msec / 1000 / 60 / 60 % 24, 10); //计算剩余的小时
  var minutes = parseInt(msec / 1000 / 60 % 60, 10); //计算剩余的分钟
  var second = parseInt(msec / 1000 % 60, 10); //计算剩余的分钟
  days = fitLen(days, 2);
  hours = fitLen(hours, 2);
  minutes = fitLen(minutes, 2);
  second = fitLen(second, 2);
  return {days, hours, minutes, second}
}

// 函数防抖：
const debounce = function(fn, wait) {
  let timer = null;
  return function () {
      let context = this
      if (timer) {
          clearTimeout(timer);
          timer = null;
      }
      timer = setTimeout(function () {
          fn.apply(context, arguments)
      }, wait)
  }
}

// 函数节流
const throttle = function (fn, gapTime) {
  let _lastTime = null;
  return function () {
    let _nowTime = + new Date()
    if (_nowTime - _lastTime > gapTime || !_lastTime) {
      fn(arguments);
      _lastTime = _nowTime
    }
  }
}

//判断是否为空对象、空数组
const isEmpty = function (obj) {
  //检验null和undefined
  if (!obj && obj !== 0 && obj !== '') {
      return true;
  }
  //检验数组
  if (Array.prototype.isPrototypeOf(obj) && obj.length === 0) {
      return true;
  }
  //检验对象
  if (Object.prototype.isPrototypeOf(obj) && Object.keys(obj).length === 0) {
      return true;
  }
  return false;
}

/**
 * 如果target(也就是FirstOBJ[key])存在，
 * 且是对象的话再去调用deepObjectMerge，
 * 否则就是FirstOBJ[key]里面没这个对象，需要与SecondOBJ[key]合并
 */
const deepObjectMerge = function(FirstOBJ, SecondOBJ) { // 深度合并对象
  for (var key in SecondOBJ) {
      FirstOBJ[key] = FirstOBJ[key] && FirstOBJ[key].toString() === "[object Object]" ?
          deepObjectMerge(FirstOBJ[key], SecondOBJ[key]) : FirstOBJ[key] = SecondOBJ[key];
  }
  return FirstOBJ;
}

// 连按五次打开\关闭调试
let vConsole = null, vi = 0
const toggleDebug = function(ctx, skip){
  vi++;
  if (vi % 5 === 0 || skip) {
    if (vConsole) {
      vConsole.destroy()
      vConsole = null;
    } else {
      vConsole = new VConsole();
      if(!ctx || ctx.$root.envs.showEnvs){
        return
      }
      Dialog.confirm({
        title: '确认框',
        message: '是否开启运行环境设置？',
        closeOnClickOverlay:false
      }).then(action=>{
        let _env = Config.envs.find(env=>{
          return `${env.isHttps?'https://':'http://'}${env.domain}` == Config.url
        })
        localStorage.setItem('env', _env&&_env.env||'prod')
        ctx.$root.envs.showEnvs = true
      }).catch(() => {})
    }
  }
}

/** 
 * flutter执行js函数
 * window[method] 定义全局方法method
 * step.postMessage 将method名传给flutter，flutter执行method
 */
 const doFlutter = ({method, message}, success, error = console.warn) => {
  if(window.step){
    window[method] = success
    step.postMessage(JSON.stringify({method,message}))
  }else{
    error('没有找到 [window.step] 方法！')
  }
}

export {
  md5,
  encryptPwd,
  isMobile,
  toFixed,
  defaultZero,
  ciphertext,
  getPhonePlatform,
  removeEndZero,
  countDown,
  fitLen,
  getCaptcha,
  isLightColor,
  randomString,
  getCursortPosition,
  setCursortPosition,
  humanNum,
  humanTime,
  debounce,
  throttle,
  isEmpty,
  deepObjectMerge,
  toggleDebug,
  doFlutter
}
